package com.yanqu.road.server.manger;

import com.yanqu.road.entity.servercenter.group.CrossMarriageGroup;
import com.yanqu.road.logic.bussiness.servercenter.ServerBussiness;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.manger.plugin.ManagerReloadListener;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class CrossMarriageGroupMgr extends TempMgr {

    private static final Logger logger = LogManager.getLogger(CrossMarriageGroupMgr.class.getName());

    private static Map<Integer, Map<Integer, CrossMarriageGroup>> channelMarriageGroupMap;

    private static Map<Integer, CrossMarriageGroup> marriageGroupMap;

    private static ManagerReloadListener managerReloadListener;
    /**
     * 分组变更前服务器列表
     */
    private static Map<Integer, List<Long>> allBeforeChangeServerList = new ConcurrentHashMap<>();

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean init() {
        return reload();
    }

    @Override
    public boolean reload() {
        reloadServerGroup();
        return true;
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    public static void reloadServerGroup() {
        Map<Integer, Map<Integer, CrossMarriageGroup>> tempChannelMarriageGroupMap = new ConcurrentHashMap<>();
        Map<Integer, CrossMarriageGroup> tempMarriageGroupMap = new ConcurrentHashMap<>();
        ServerBussiness.getCrossMarriageGroupMap(tempChannelMarriageGroupMap, tempMarriageGroupMap);
        channelMarriageGroupMap = tempChannelMarriageGroupMap;
        marriageGroupMap = tempMarriageGroupMap;
        notifyReload();
        allBeforeChangeServerList = initAllBeforeChangeServerList();
    }

    private static Map<Integer, List<Long>> initAllBeforeChangeServerList() {
        Map<Integer, List<Long>> dataMap = new ConcurrentHashMap<>();
        for (Map.Entry<Integer, Map<Integer, CrossMarriageGroup>> dataEntry : channelMarriageGroupMap.entrySet()) {
            if (!dataMap.containsKey(dataEntry.getKey())) {
                dataMap.put(dataEntry.getKey(), new ArrayList<>());
            }
            List<Long> dataList = dataMap.get(dataEntry.getKey());
            for (CrossMarriageGroup marriageGroup : dataEntry.getValue().values()) {
                dataList.addAll(marriageGroup.getServerList());
            }
        }
        return dataMap;
    }

    public static void addReloadListener(ManagerReloadListener reloadListener) {
        managerReloadListener = reloadListener;
    }

    private static void notifyReload() {
        if (null != managerReloadListener) {
            managerReloadListener.notifyReload();
        }
    }

    public static Map<Integer, CrossMarriageGroup> getCrossMarriageGroupMap(int channelId) {
        return channelMarriageGroupMap.get(channelId);
    }

    public static List<CrossMarriageGroup> getCrossMarriageGroupList(int channelId) {
        Map<Integer, CrossMarriageGroup> dataMap = getCrossMarriageGroupMap(channelId);
        if (null != dataMap) {
            return new ArrayList<>(dataMap.values());
        }
        return new ArrayList<>();
    }

    public static CrossMarriageGroup getCrossMarriageGroup(int groupId) {
        return marriageGroupMap.get(groupId);
    }

    public static int getGroupIdByServerId(long serverId) {
        int groupId = 0;
        CrossMarriageGroup serverGroup = getCrossMarriageGroupByServerId(serverId);
        if (null != serverGroup) {
            groupId = serverGroup.getGroupId();
        }
        return groupId;
    }

    public static CrossMarriageGroup getCrossMarriageGroupByServerId(long serverId) {
        CrossMarriageGroup marriageGroup = null;
        int channelId = ServerListMgr.getChannelId(serverId);
        Map<Integer, CrossMarriageGroup> dataMap = getCrossMarriageGroupMap(channelId);
        if (null != dataMap) {
            for (CrossMarriageGroup tempGroup : dataMap.values()) {
                if (tempGroup.getServerList().contains(serverId)) {
                    marriageGroup = tempGroup;
                    break;
                }
            }
        }
        return marriageGroup;
    }

    /**
     * 是否开启跨服联姻
     *
     * @param marriageGroup
     * @return
     */
    public static boolean canCrossMarriage(CrossMarriageGroup marriageGroup) {
        if (null == marriageGroup) {
            return false;
        }
        return marriageGroup.isCrossMarriage();
    }

    /**
     * 是否开启跨服联姻
     *
     * @param serverId
     * @return
     */
    public static boolean canCrossMarriage(long serverId) {
        CrossMarriageGroup marriageGroup = getCrossMarriageGroupByServerId(serverId);
        return canCrossMarriage(marriageGroup);
    }

    public static List<Long> getPartyServerList(long serverId) {
        for (CrossMarriageGroup group : marriageGroupMap.values()) {
            if (group.isCrossBanquet()) {
                List<Long> serverList = group.getServerList();
                if (serverList.contains(serverId)) {
                    return serverList;
                }
            }
        }
        List<Long> list = new ArrayList<>();
        list.add(serverId);
        return list;
    }


    public static List<Long> getFeastPartyServerList(long serverId) {
        for (CrossMarriageGroup group : marriageGroupMap.values()) {
            if (group.isCrossBanquet()) {
                List<Long> serverList = group.getServerList();
                if (serverList.contains(serverId)) {
                    return serverList;
                }
            }
        }
        List<Long> list = new ArrayList<>();
        list.add(serverId);
        return list;
    }


    /**
     * 根据渠道编号获取变更前服务器编号
     *
     * @param channelId
     * @return
     */
    public static List<Long> getBeforeChangeServerList(int channelId) {
        List<Long> dataList = new ArrayList<>();
        if (allBeforeChangeServerList.containsKey(channelId)) {
            dataList.addAll(allBeforeChangeServerList.get(channelId));
        }
        return dataList;
    }
}
